package JUC;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author 曹见朋
 * @create 2024-07-03-20:25
 */
public class ClockNumber {

    int number = 0;

    AtomicLong atomicLong = new AtomicLong(0);

    LongAdder longAdder = new LongAdder();

    LongAccumulator longAccumulator = new LongAccumulator((x, y)-> x + y, 0);

    public synchronized void clickBySynchronized(){
        number++;
    }

    public void clickByAtomicInteger(){
        atomicLong.getAndIncrement();
    }

    public void clickByLongAddr(){
        longAdder.increment();
    }

    public void clickByLongAccumulator(){
        longAccumulator.accumulate(1);
    }

    public static void main(String[] args) throws InterruptedException {
        m1();  // 21毫秒
        m2();  // 9毫秒
        m3();  // 9毫秒
        m4();  // 9毫秒
    }

    public static void m1() throws InterruptedException {
        ClockNumber clockNumber = new ClockNumber();
        CountDownLatch countDownLatch = new CountDownLatch(1000);
        long begin = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            new Thread(()->{
                for(int j = 0; j < 100000; j++){
                    clockNumber.clickBySynchronized();
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("m1累加后数字为：" + clockNumber.number + " 总共用时：" + (end - begin) + "毫秒.");
    }

    public static void m2() throws InterruptedException {
        ClockNumber clockNumber = new ClockNumber();
        CountDownLatch countDownLatch = new CountDownLatch(1000);
        long begin = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            new Thread(()->{
                for(int j = 0; j < 100000; j++){
                    clockNumber.clickByAtomicInteger();
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("m2累加后数字为：" + clockNumber.atomicLong.get() + " 总共用时：" + (end - begin) + "毫秒.");
    }

    public static void m3() throws InterruptedException {
        ClockNumber clockNumber = new ClockNumber();
        CountDownLatch countDownLatch = new CountDownLatch(1000);
        long begin = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            new Thread(()->{
                for(int j = 0; j < 100000; j++){
                    clockNumber.clickByLongAddr();
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("m3累加后数字为：" + clockNumber.longAdder.toString() + " 总共用时：" + (end - begin) + "毫秒.");
    }

    public static void m4() throws InterruptedException {
        ClockNumber clockNumber = new ClockNumber();
        CountDownLatch countDownLatch = new CountDownLatch(1000);
        long begin = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            new Thread(()->{
                for(int j = 0; j < 100000; j++){
                    clockNumber.clickByLongAccumulator();
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("m4累加后数字为：" + clockNumber.longAccumulator.get() + " 总共用时：" + (end - begin) + "毫秒.");
    }
}
